
/** 
 * 创建数据 
 * @param data 数据源
 * @param id id 名称
 * @param pid 父级id 名称
 * @param root 根节点pid的值
 * */
export function createTree<T>(data: T[], id: string, pid: string, root: any = 0) {

    type TreeNote = T & { children: T[] };

    return data
        .filter((item: any) => item[pid] === root)
        .map(e => new TreeItem(e, data, id, pid) as any) as TreeNote[];
}

export class TreeItem {

    /** 当前阶段数据 */
    private $info: any;

    /** 数据源 */
    private $data: any[];

    /** 父级id 名称 */
    private $pid: string;

    /** id 名称 */
    private $id: string;

    /** 计算好的孩子 */
    private $children?: TreeItem[];

    /**
     * @param data 数据源
     * @param id id 名称
     * @param pid 父级id 的值
     */
    constructor(info: any, data: any[], id: string, pid: string) {
        this.$info = info;
        this.$data = data;
        this.$pid = pid;
        this.$id = id;

        for (const key in info) {
            if (Object.prototype.hasOwnProperty.call(info, key)) {
                const element = info[key];
                this[key] = element;
            }
        }
    }

    /** 孩子 */
    get children() {
        const c = this.$children
            || (
                this.$children = this.$data.filter((item: any) => item[this.$pid] === this.$info[this.$id]).map(e => new TreeItem(e, this.$data, this.$id, this.$pid))
            );

        return c.length > 0 ? c : undefined;
    }
}